package com.supermap.dataservice.grid.griddata.service;

import com.supermap.dataservice.grid.NetCDFAllUtil;
import com.supermap.dataservice.grid.griddata.entity.GridData;
import com.supermap.dataservice.grid.griddata.entity.GridProduct;
import com.supermap.dataservice.grid.griddata.util.ArrayUtil;
import com.supermap.dataservice.util.Arith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ucar.nc2.NetcdfFile;

import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

/**
 * @Author:zhoujian
 * @Desciption:
 * @date:2019-07-15 17:39
 * @version:v1.0.0
 */
@Service
public class NetcdfServiceImpl {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    public GridData read(GridProduct gridProduct) throws Exception
    {
        String filePath = gridProduct.getNcUrl();
        String element = gridProduct.getElementCode();
        GridData gridData = getGrid(filePath, element);
        gridData.setValid(gridProduct.getValidCode());
        gridData.setLevel(Integer.parseInt(gridProduct.getLevelCode()));
        return gridData;
    }

    private GridData getGrid(String filePath , String element) throws Exception {
        GridData gridData = null;
        NetcdfFile netcdfFile = null;
        try
        {

            netcdfFile = NetcdfFile.open(filePath);

            // left bottom right top 数据范围
            Rectangle2D rectangle2d = NetCDFAllUtil.getGeoBounds(netcdfFile);
            float left =  Arith.round((float) rectangle2d.getX(),2);
            float bottom = Arith.round((float) rectangle2d.getY(),2);
            float right = Arith.round((float) rectangle2d.getWidth() + left,2);
            float top = Arith.round((float) rectangle2d.getHeight() + bottom,2);
            //数据开始的点
            float startLon = left;
            float startLat = top;

            // 列数
            int cols = NetCDFAllUtil.getCols(netcdfFile);
            //行数
            int rows = NetCDFAllUtil.getRows(netcdfFile);
            //分辨率
            Point2D point2d = NetCDFAllUtil.getCellSize(netcdfFile);
            float deltaX = Arith.round((float) point2d.getX(), 3);
            float deltaY = Arith.round((float) point2d.getY(),3);
            //单位
            String unit = "";
            try
            {
                unit = NetCDFAllUtil.getUnit(element, netcdfFile);
            }
            catch (Exception e1)
            {
                unit = "-";
            }

            float[][] grid = null;
            //默认是缺测值
            float dataMax = 999999;
            float dataMin = 999999;

            //数据
            float[] data = NetCDFAllUtil.getValues(element, netcdfFile);
            //一维数据转换成二维数组
            grid = arrayTwoDimensionalArray(data, rows, cols , 1);
            dataMax = Arith.round(ArrayUtil.max(data), 1) ;
            dataMin = Arith.round(ArrayUtil.min(data),1);
            //最高温和最低温时每个格点出现的时间点

            gridData = new GridData(startLon , right , top , bottom , deltaX , deltaY , cols , rows , 0,element , unit , dataMax , dataMin, 0,null,grid);
        }
        catch (Exception e)
        {
            logger.error("解析格点数据文件netcdf异常 ，方法参数：  \n异常信息：" + e.toString());
            throw new Exception("解析格点数据文件异常 , 异常信息： " + e.toString());
        }finally{
            if (netcdfFile != null)
            {
                netcdfFile.close();
            }
        }

        return gridData;
    }

    /**
     *
     * @Description: 一维数组转换成二维数组并精度控制，而且纬度方向转置
     * @author zhoujian
     * @return float[][]
     * @throws
     */
    private float[][] arrayTwoDimensionalArray(float[] array , int rows ,int cols , int accuracy){
        float[][] newArray = new float[rows][cols];
        for (int i = rows - 1; i >= 0 ; i--)
        {
            for (int j = 0; j < cols; j++)
            {
                newArray[rows - 1 - i][j] = Arith.round(array[i * cols + j], accuracy);
            }
        }
        return newArray;
    }
}